#ifndef DYNAMIC_TEXTURE_H
#define DYNAMIC_TEXTURE_H

#include "glew.h"
#include <string>
#include "texture.h"
#include <gl/gl.h>
#include "logger.h"

using namespace std;

//! Klasa umozliwia latwe renderowanie do tekstury
class DynamicTexture
{
 typedef unsigned int uint;

 private:

	Texture texture;
	uint FBOid;
	uint RBOid;
	string lastError;
	int viewportX;
	int viewportY;
	int viewportWidth;
	int viewportHeight;
	int replacedTexture;

	bool CheckFramebufferStatus();

 public:

	//static void InitializeFBO(); 

	DynamicTexture( uint width, uint height ) : texture( 0, width, height, GL_RGBA, GL_TEXTURE_2D, true ), FBOid(0), RBOid(0), lastError("") 
	{  }

	~DynamicTexture();

	//! Przed uzyciem dynamicznej tekstury nalezy ja zainicjalizowac
	bool InitializeDynamicTexture();

	//! Cala geometria zostanie przekierowana do tekstury po wywolaniu tej funkjci
	/*!
		Uzycie:
		obiekt.BeginTextureRendering();
			... renderujemy do obiektu ...
		obiekt.EndTextureRendering();

		... renderujemy normalnie ...
	*/
	void BeginTextureRendering();

	//! Konczy przekierowanie geometri do tekstury i ustawia rendering do zwyklego bufora okna
	/*!
		obiekt.BeginTextureRendering();
			... renderujemy do obiektu ...
		obiekt.EndTextureRendering();

		... renderujemy normalnie ...
	*/
	void EndTextureRendering();

	//! Generuje mipmapy dla dynamicznej tekstury
	/*!
		Poniewaz zawartosc tej tekstury zmienia sie dynamicznie, dlatego trzeba na bierzaco generowac dla niej mipmapy aby byly one zgodne z aktualna zawartoscia tekstury.
	*/
	void GenerateMipmaps();

	//! Wywolujemy jesli chcemy teksturowac dynamiczna tekstura
	/*!
		Uzycie:
		obiekt.Bind();
			... teksturujemy ...
		obiekt.unbind();
	*/
	void Bind();

	//! Wywolujemy jesli skonczylismy teksturowanie 
	/*!
		Uzycie:
		obiekt.Bind();
			... teksturujemy ...
		obiekt.unbind();
	*/
	void Unbind();

	//! Zwraca informacje o ostatnim bledzie
	string GetLastError()
	{ return lastError; }
};

//-------------------------------------------- InitializeFBO -----------------------------------------------------//
//void DynamicTexture::InitializeFBO()
//{
	//const char* ext = (const char *)glGetString(GL_EXTENSIONS);

 //   if( string( ext ).find( "GL_EXT_framebuffer_object" ) )
 //   {
 //       // get pointers to GL functions
 //       glGenFramebuffersEXT                     = (PFNGLGENFRAMEBUFFERSEXTPROC)wglGetProcAddress("glGenFramebuffersEXT");
 //       glDeleteFramebuffersEXT                  = (PFNGLDELETEFRAMEBUFFERSEXTPROC)wglGetProcAddress("glDeleteFramebuffersEXT");
 //       glBindFramebufferEXT                     = (PFNGLBINDFRAMEBUFFEREXTPROC)wglGetProcAddress("glBindFramebufferEXT");
 //       glCheckFramebufferStatusEXT              = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)wglGetProcAddress("glCheckFramebufferStatusEXT");
 //       glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)wglGetProcAddress("glGetFramebufferAttachmentParameterivEXT");
 //       glGenerateMipmapEXT                      = (PFNGLGENERATEMIPMAPEXTPROC)wglGetProcAddress("glGenerateMipmapEXT");
 //       glFramebufferTexture2DEXT                = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)wglGetProcAddress("glFramebufferTexture2DEXT");
 //       glFramebufferRenderbufferEXT             = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)wglGetProcAddress("glFramebufferRenderbufferEXT");
 //       glGenRenderbuffersEXT                    = (PFNGLGENRENDERBUFFERSEXTPROC)wglGetProcAddress("glGenRenderbuffersEXT");
 //       glDeleteRenderbuffersEXT                 = (PFNGLDELETERENDERBUFFERSEXTPROC)wglGetProcAddress("glDeleteRenderbuffersEXT");
 //       glBindRenderbufferEXT                    = (PFNGLBINDRENDERBUFFEREXTPROC)wglGetProcAddress("glBindRenderbufferEXT");
 //       glRenderbufferStorageEXT                 = (PFNGLRENDERBUFFERSTORAGEEXTPROC)wglGetProcAddress("glRenderbufferStorageEXT");
 //       glGetRenderbufferParameterivEXT          = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)wglGetProcAddress("glGetRenderbufferParameterivEXT");
 //       glIsRenderbufferEXT                      = (PFNGLISRENDERBUFFEREXTPROC)wglGetProcAddress("glIsRenderbufferEXT");

 //       // check once again FBO extension
 //       if(glGenFramebuffersEXT && glDeleteFramebuffersEXT && glBindFramebufferEXT && glCheckFramebufferStatusEXT &&
 //          glGetFramebufferAttachmentParameterivEXT && glGenerateMipmapEXT && glFramebufferTexture2DEXT && glFramebufferRenderbufferEXT &&
 //          glGenRenderbuffersEXT && glDeleteRenderbuffersEXT && glBindRenderbufferEXT && glRenderbufferStorageEXT &&
 //          glGetRenderbufferParameterivEXT && glIsRenderbufferEXT)
 //       {
 //          // logout << "Video card supports GL_EXT_framebuffer_object." << endl;
 //       }
 //       else
 //       {
	//		exit(0);
 //           //logout << "Video card does NOT support GL_EXT_framebuffer_object." << endl;
 //       }
 //   }
//}

#endif